﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SOM.Model;
using SOM.Control;
using System.Threading;


namespace SOM.UI
{
    public partial class MainWindow : Form
    {
        private string folderName=null;
        private MainWindowCtrl mainWindowsControl;
        private int lenNgram;
        private int sizeDict;
        private int mismatchValue;
        private int EpochNum;
        private int tessalationLvl;
        private double learningRate;
        private double KernelWidth;

        public BackgroundWorker BGWORKER
        {
            get
            {
                return bgWorkerMain;
            }

        }

        public MainWindow()
        {
            InitializeComponent();
            mainWindowsControl = new MainWindowCtrl(this);
            initBGworker();
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
                return cp;
            }
        } 

        private void initBGworker()
        {
            // Create a background worker thread that ReportsProgress &
            // SupportsCancellation
            // Hook up the appropriate events.
            bgWorkerMain.DoWork += new DoWorkEventHandler(bgWorkerMain_DoWork);
            bgWorkerMain.ProgressChanged += new ProgressChangedEventHandler(bgWorkerMain_ProgressChanged);
            bgWorkerMain.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorkerMain_RunWorkerCompleted);        
        }

        void bgWorkerMain_DoWork(object sender, DoWorkEventArgs e)
        {
            /* Seperate BG thread to run the Analysis task
             * */
            mainWindowsControl.setAnalysisRunParams(folderName, lenNgram, sizeDict, mismatchValue,EpochNum,tessalationLvl,learningRate,KernelWidth);
            mainWindowsControl.runAnalysis();
        }

        void bgWorkerMain_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            //Change the status of the buttons on the UI accordingly
            btnStart.Enabled = true;
            MainProgressBar.Value = 0;

            // Check to see if an error occurred in the
            // background process.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
                return;
            }

            // Check to see if the background process was cancelled.
            if (e.Cancelled)
            {
                MessageBox.Show("Processing cancelled.");
                return;
            }

            // Everything completed normally.
            // process the response using e.Result
            MessageBox.Show("Processing is complete.");
            new UI.ResultForm(mainWindowsControl.SOFM).Show();
            //MessageBox.Show(e.Result.ToString());
        }

        void bgWorkerMain_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Chabge the progress bar fill
            MainProgressBar.Value = e.ProgressPercentage;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            //folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
            DialogResult result = folderBrowserDialog1.ShowDialog();
            
            if (result == DialogResult.OK)
            {
                folderName = folderBrowserDialog1.SelectedPath;
                textBoxSamplesPath.Text = folderName;
            }
        }

        private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
        {

        }

        private void btnStart_Click(object sender, EventArgs e)
        {

            EpochNum = int.Parse(textBoxEpochsNum.Text.ToString());
            learningRate = double.Parse(textBoxLearnRate.Text.ToString());
            KernelWidth = double.Parse(textBoxKernelWidth.Text.ToString());
            if (folderName == null)
            {
                MessageBox.Show("Select Samples Directory");
                return;
            }

            //Change the status of the buttons on the UI accordingly
            //The start button is disabled as soon as the background operation is started
            //The Cancel button is enabled so that the user can stop the operation 
            //at any point of time during the execution
            btnStart.Enabled = false;
            // Kickoff the worker thread to begin it's DoWork function.
            bgWorkerMain.RunWorkerAsync();
        }

        //Not Used anymore but left for future purposes
        private void btnStopRun_Click(object sender, EventArgs e)
        {
            if (bgWorkerMain.IsBusy)
            {

                // Notify the worker thread that a cancel has been requested.

                // The cancel will not actually happen until the thread in the

                // DoWork checks the bgWorkerMain.CancellationPending flag. 

                bgWorkerMain.CancelAsync();

            }
        }

        private void cbNGramLen_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (int.Parse(cbNGramLen.SelectedItem.ToString()) == 6)
            {
               
                this.cbDictSize.Items.Clear();
                this.cbDictSize.Items.AddRange(new object[] {"4096"});
                this.cbDictSize.SelectedIndex = 0;

                this.cbMismatchVal.Items.Clear();
                this.cbMismatchVal.Items.AddRange(new object[] { "0" });
                this.cbMismatchVal.SelectedIndex = 0;
            }
            else
            {
                this.cbDictSize.Items.Clear();
                this.cbDictSize.Items.AddRange(new object[] {"100","200"});

                this.cbMismatchVal.Items.Clear();
                this.cbMismatchVal.Items.AddRange(new object[] { "1", "2" });

            }
            lenNgram=int.Parse(cbNGramLen.SelectedItem.ToString());
        }
        
        private void cbDictSize_SelectionChangeCommitted(object sender, EventArgs e)
        {
            sizeDict = int.Parse(cbDictSize.SelectedItem.ToString());
        
        }
        
        private void cbMismatchVal_SelectionChangeCommitted(object sender, EventArgs e)
        {
            mismatchValue = int.Parse(cbMismatchVal.SelectedItem.ToString());

        }

        private void cbTesslationLvl_SelectionChangeCommitted(object sender, EventArgs e)
        {
            tessalationLvl = int.Parse(cbTesslationLvl.SelectedItem.ToString());
            textBoxNetworkSize.Text = (10 * Math.Pow(2,2*(tessalationLvl-1)) + 2).ToString();

        }

        private void textBoxEpochsNum_TextChanged(object sender, EventArgs e)
        {
            string actualdata = string.Empty;
            char[] entereddata = textBoxEpochsNum.Text.ToCharArray();
            foreach (char aChar in entereddata.AsEnumerable())
            {
                if (Char.IsDigit(aChar))
                {
                    actualdata = actualdata + aChar;
                    // MessageBox.Show(aChar.ToString());
                }
                else
                {
                    MessageBox.Show(aChar + " is not numeric");
                    actualdata.Replace(aChar, ' ');
                    actualdata.Trim();
                }
            }
            textBoxEpochsNum.Text = actualdata;

        }

        private void textBoxLearnRate_TextChanged(object sender, EventArgs e)
        {
            //MessageBox.Show(" is not numeric");
        }

        private void userGuideToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new GuideForm("mw");
        }
    }
}
